/*
    SDL - Simple DirectMedia Layer
    Partial implementation of SDL library (originally written by
    Sam Lantinga <slouken@libsdl.org>) for the particular purpose to support
    Prequengine (http://code.google.com/p/prequengine/) on BlackBerry(tm)
    tablets and smartphones.

    Copyright (C) 2013  xlamsp

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

    xlamsp@gmail.com
*/

#ifndef SDL_EVENTS_H_
#define SDL_EVENTS_H_

#include "SDL_stdinc.h"
#include "SDL_keyboard.h"
#include "SDL_mouse.h"


/** @name General keyboard/mouse state definitions */
/*@{*/
#define SDL_RELEASED    0
#define SDL_PRESSED     1
/*@}*/

/** Event enumerations */
typedef enum {
    SDL_NOEVENT = 0,            /**< Unused (do not remove) */
    SDL_ACTIVEEVENT,            /**< Application loses/gains visibility */
    SDL_KEYDOWN,                /**< Keys pressed */
    SDL_KEYUP,                  /**< Keys released */
    SDL_MOUSEMOTION,            /**< Mouse moved */
    SDL_MOUSEBUTTONDOWN,        /**< Mouse button pressed */
    SDL_MOUSEBUTTONUP,          /**< Mouse button released */
    SDL_JOYAXISMOTION,          /**< Joystick axis motion */
    SDL_JOYBALLMOTION,          /**< Joystick trackball motion */
    SDL_JOYHATMOTION,           /**< Joystick hat position change */
    SDL_JOYBUTTONDOWN,          /**< Joystick button pressed */
    SDL_JOYBUTTONUP,            /**< Joystick button released */
    SDL_QUIT,                   /**< User-requested quit */
    SDL_SYSWMEVENT,             /**< System specific event */
    SDL_EVENT_RESERVEDA,        /**< Reserved for future use.. */
    SDL_EVENT_RESERVEDB,        /**< Reserved for future use.. */
    SDL_VIDEORESIZE,            /**< User resized video mode */
    SDL_VIDEOEXPOSE,            /**< Screen needs to be redrawn */
    SDL_EVENT_RESERVED2,        /**< Reserved for future use.. */
    SDL_EVENT_RESERVED3,        /**< Reserved for future use.. */
    SDL_EVENT_RESERVED4,        /**< Reserved for future use.. */
    SDL_EVENT_RESERVED5,        /**< Reserved for future use.. */
    SDL_EVENT_RESERVED6,        /**< Reserved for future use.. */
    SDL_EVENT_RESERVED7,        /**< Reserved for future use.. */
    /** Events SDL_USEREVENT through SDL_MAXEVENTS-1 are for your use */
    SDL_USEREVENT = 24,
    /** This last event is only for bounding internal arrays
    *  It is the number of bits in the event mask datatype -- Uint32
    */
    SDL_NUMEVENTS = 32
} SDL_EventType;

/** @name Predefined event masks */
/*@{*/
#define SDL_EVENTMASK(X)        (1<<(X))
typedef enum {
    SDL_ACTIVEEVENTMASK         = SDL_EVENTMASK(SDL_ACTIVEEVENT),
    SDL_KEYDOWNMASK             = SDL_EVENTMASK(SDL_KEYDOWN),
    SDL_KEYUPMASK               = SDL_EVENTMASK(SDL_KEYUP),
    SDL_KEYEVENTMASK            = SDL_EVENTMASK(SDL_KEYDOWN) |
                                SDL_EVENTMASK(SDL_KEYUP),
    SDL_MOUSEMOTIONMASK         = SDL_EVENTMASK(SDL_MOUSEMOTION),
    SDL_MOUSEBUTTONDOWNMASK     = SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN),
    SDL_MOUSEBUTTONUPMASK       = SDL_EVENTMASK(SDL_MOUSEBUTTONUP),
    SDL_MOUSEEVENTMASK          = SDL_EVENTMASK(SDL_MOUSEMOTION) |
                                SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN) |
                                SDL_EVENTMASK(SDL_MOUSEBUTTONUP),
    SDL_JOYAXISMOTIONMASK       = SDL_EVENTMASK(SDL_JOYAXISMOTION),
    SDL_JOYBALLMOTIONMASK       = SDL_EVENTMASK(SDL_JOYBALLMOTION),
    SDL_JOYHATMOTIONMASK        = SDL_EVENTMASK(SDL_JOYHATMOTION),
    SDL_JOYBUTTONDOWNMASK       = SDL_EVENTMASK(SDL_JOYBUTTONDOWN),
    SDL_JOYBUTTONUPMASK         = SDL_EVENTMASK(SDL_JOYBUTTONUP),
    SDL_JOYEVENTMASK            = SDL_EVENTMASK(SDL_JOYAXISMOTION) |
                                SDL_EVENTMASK(SDL_JOYBALLMOTION) |
                                SDL_EVENTMASK(SDL_JOYHATMOTION) |
                                SDL_EVENTMASK(SDL_JOYBUTTONDOWN) |
                                SDL_EVENTMASK(SDL_JOYBUTTONUP),
    SDL_VIDEORESIZEMASK         = SDL_EVENTMASK(SDL_VIDEORESIZE),
    SDL_VIDEOEXPOSEMASK         = SDL_EVENTMASK(SDL_VIDEOEXPOSE),
    SDL_QUITMASK                = SDL_EVENTMASK(SDL_QUIT),
    SDL_SYSWMEVENTMASK          = SDL_EVENTMASK(SDL_SYSWMEVENT)
} SDL_EventMask;
#define SDL_ALLEVENTS           0xFFFFFFFF
/*@}*/

/** Keyboard event structure */
typedef struct SDL_KeyboardEvent {
    Uint8 type;     /**< SDL_KEYDOWN or SDL_KEYUP */
    Uint8 which;    /**< The keyboard device index */
    Uint8 state;    /**< SDL_PRESSED or SDL_RELEASED */
    SDL_keysym keysym;
} SDL_KeyboardEvent;

/** Mouse button event structure */
typedef struct SDL_MouseButtonEvent {
    Uint8 type;     /**< SDL_MOUSEBUTTONDOWN or SDL_MOUSEBUTTONUP */
    Uint8 which;    /**< The mouse device index */
    Uint8 button;   /**< The mouse button index */
    Uint8 state;    /**< SDL_PRESSED or SDL_RELEASED */
    Uint16 x, y;    /**< The X/Y coordinates of the mouse at press time */
} SDL_MouseButtonEvent;

/** The "quit requested" event */
typedef struct SDL_QuitEvent {
    Uint8 type;     /**< SDL_QUIT */
} SDL_QuitEvent;

/** General event structure */
typedef union SDL_Event {
    Uint8 type;
    SDL_KeyboardEvent key;
    SDL_MouseButtonEvent button;
    SDL_QuitEvent quit;
} SDL_Event;

/* Function prototypes */

/** Pumps the event loop, gathering events from the input devices.
 *  This function updates the event queue and internal input device state.
 *  This should only be run in the thread that sets the video mode.
 */
extern void SDL_PumpEvents(void);

typedef enum {
    SDL_ADDEVENT,
    SDL_PEEKEVENT,
    SDL_GETEVENT
} SDL_eventaction;

/**
 *  Checks the event queue for messages and optionally returns them.
 *
 *  If 'action' is SDL_ADDEVENT, up to 'numevents' events will be added to
 *  the back of the event queue.
 *  If 'action' is SDL_PEEKEVENT, up to 'numevents' events at the front
 *  of the event queue, matching 'mask', will be returned and will not
 *  be removed from the queue.
 *  If 'action' is SDL_GETEVENT, up to 'numevents' events at the front
 *  of the event queue, matching 'mask', will be returned and will be
 *  removed from the queue.
 *
 *  @return
 *  This function returns the number of events actually stored, or -1
 *  if there was an error.
 *
 *  This function is thread-safe.
 */
extern int SDL_PeepEvents(SDL_Event *events, int numevents,
                                SDL_eventaction action, Uint32 mask);

/** Polls for currently pending events, and returns 1 if there are any pending
 *  events, or 0 if there are none available.  If 'event' is not NULL, the next
 *  event is removed from the queue and stored in that area.
 */
extern int SDL_PollEvent(SDL_Event *event);

/** Add an event to the event queue.
 *  This function returns 0 on success, or -1 if the event queue was full
 *  or there was some other error.
 */
extern int SDL_PushEvent(SDL_Event *event);

#endif /* SDL_EVENTS_H_ */

